#include<iostream>
#include<algorithm>
// zdl:: 这道题目非常的有意思哈，现在我们就来尝试解决一下，大多数的时候这个题目还是具有很大的迷惑性的，很多人可能会尝试使用分组背包!
using namespace std;
const int N = 1010, M = N * N;
struct stu
{
    int h, id;
}e[M];

int n, s, m;
int kind;
int cnt[N];
int main()
{
    cin >> n >> s;
    
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1 ;j <= s; j++)
        {
            e[++m].id = i;
            cin >> e[m].h;
        }
    }
    // zdl:: 接下来就直接进行排序使用这样的方法可以直接将这个数组初始化！！
    sort(e + 1, e + 1 + m, [](stu& x, stu& y){
        return x.h < y.h;
    });
    // 现在使用滑动窗口
    int ret = 0x3f3f3f3f;
    for (int l = 1, r = 1; r <= m; r++)
    {
        int id = e[r].id;
        cnt[id]++;
        if (cnt[id] == 1) kind++;
        while (kind == n)
        {
            // 现在开始更新结果
            ret = min(ret, e[r].h - e[l].h);
            cnt[e[l].id]--;
            if (cnt[e[l].id] == 0) kind--;
            l++;
        }
    }
// zdl:: 按照这个逻辑到最后可以直接更新出结果！！！
    cout << ret << endl;
    return 0;
}